home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 September / september_2000.iso / intercd / root / ^Linux / cdrtools-1.10 / inc / align_test.c next >
Encoding:
C/C++ Source or Header  |  2000-01-07  |  14.4 KB  |  675 lines

  1. /* @(#)align_test.c    1.12 00/01/07 Copyright 1995 J. Schilling */
  2. #ifndef    lint
  3. static    char sccsid[] =
  4.     "@(#)align_test.c    1.12 00/01/07 Copyright 1995 J. Schilling";
  5. #endif
  6. /*
  7.  *    Generate machine dependant align.h
  8.  *
  9.  *    Copyright (c) 1995 J. Schilling
  10.  */
  11. /*
  12.  * This program is free software; you can redistribute it and/or modify
  13.  * it under the terms of the GNU General Public License as published by
  14.  * the Free Software Foundation; either version 2, or (at your option)
  15.  * any later version.
  16.  *
  17.  * This program is distributed in the hope that it will be useful,
  18.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20.  * GNU General Public License for more details.
  21.  *
  22.  * You should have received a copy of the GNU General Public License
  23.  * along with this program; see the file COPYING.  If not, write to
  24.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  25.  */
  26.  
  27. #include <mconfig.h>
  28. #include <stdio.h>
  29. #include <standard.h>
  30.  
  31. /*#define    FORCE_ALIGN*/
  32. /*#define    OFF_ALIGN*/
  33. /*#define    CHECK_ALIGN*/
  34.  
  35. EXPORT    int    main    __PR((int ac, char** av));
  36.  
  37. #if    !defined(FORCE_ALIGN) && !defined(OFF_ALIGN) &&    !defined(CHECK_ALIGN)
  38. #define    OFF_ALIGN
  39. #endif
  40.  
  41. char    buf[8192+1024];
  42. char    *buf_aligned;
  43.  
  44. #ifdef    FORCE_ALIGN
  45. #    undef    CHECK_ALIGN
  46. #    undef    OFF_ALIGN
  47. #endif
  48.  
  49. #ifdef    CHECK_ALIGN
  50. #    undef    FORCE_ALIGN
  51. #    undef    OFF_ALIGN
  52. #endif
  53.  
  54. #ifdef    OFF_ALIGN
  55. #    undef    FORCE_ALIGN
  56. #    undef    CHECK_ALIGN
  57. #endif
  58.  
  59.  
  60. #ifdef    FORCE_ALIGN
  61.  
  62. #define    ALIGN_short    sizeof (short)
  63. #define    ALIGN_int    sizeof (int)
  64. #define    ALIGN_long    sizeof (long)
  65. #define    ALIGN_longlong    sizeof (long long)
  66. #define    ALIGN_float    sizeof (float)
  67. #define    ALIGN_double    sizeof (double)
  68. #define    ALIGN_ptr    sizeof (char *)
  69.  
  70. #endif
  71.  
  72. #ifdef    CHECK_ALIGN
  73.  
  74. #include <signal.h>
  75. #include <setjmp.h>
  76. LOCAL    jmp_buf    jb;
  77.  
  78. LOCAL    int    check_align    __PR((int (*)(char*, int), void (*)(char*, int), int));
  79. LOCAL    int    check_short    __PR((char *, int));
  80. LOCAL    int    check_int    __PR((char *, int));
  81. LOCAL    int    check_long    __PR((char *, int));
  82. LOCAL    int    check_longlong    __PR((char *, int));
  83. LOCAL    int    check_float    __PR((char *, int));
  84. LOCAL    int    check_double    __PR((char *, int));
  85. LOCAL    int    check_ptr    __PR((char *, int));
  86.  
  87. LOCAL    int    speed_check    __PR((char *, void (*)(char*, int), int));
  88. LOCAL    void    speed_short    __PR((char *, int));
  89. LOCAL    void    speed_int    __PR((char *, int));
  90. LOCAL    void    speed_long    __PR((char *, int));
  91. LOCAL    void    speed_longlong    __PR((char *, int));
  92. LOCAL    void    speed_float    __PR((char *, int));
  93. LOCAL    void    speed_double    __PR((char *, int));
  94. LOCAL    void    speed_ptr    __PR((char *, int));
  95.  
  96. #define    ALIGN_short    check_align(check_short, speed_short, sizeof (short))
  97. #define    ALIGN_int    check_align(check_int, speed_int, sizeof (int))
  98. #define    ALIGN_long    check_align(check_long, speed_long, sizeof (long))
  99. #define    ALIGN_longlong    check_align(check_longlong, speed_longlong, sizeof (long long))
  100. #define    ALIGN_float    check_align(check_float, speed_float, sizeof (float))
  101. #define    ALIGN_double    check_align(check_double, speed_double, sizeof (double))
  102. #define    ALIGN_ptr    check_align(check_ptr, speed_ptr, sizeof (char *))
  103.  
  104. #endif
  105.  
  106. #ifdef    OFF_ALIGN
  107.  
  108. #define    sm_off(s, m)    ((int)&((s)0)->m)
  109.  
  110. LOCAL    int    off_short    __PR((void));
  111. LOCAL    int    off_int        __PR((void));
  112. LOCAL    int    off_long    __PR((void));
  113. LOCAL    int    off_longlong    __PR((void));
  114. LOCAL    int    off_float    __PR((void));
  115. LOCAL    int    off_double    __PR((void));
  116. LOCAL    int    off_ptr        __PR((void));
  117.  
  118. #define    ALIGN_short    off_short()
  119. #define    ALIGN_int    off_int()
  120. #define    ALIGN_long    off_long()
  121. #define    ALIGN_longlong    off_longlong()
  122. #define    ALIGN_float    off_float()
  123. #define    ALIGN_double    off_double()
  124. #define    ALIGN_ptr    off_ptr()
  125.  
  126. #endif
  127.  
  128. LOCAL    void    printmacs    __PR((void));
  129.  
  130. #ifdef    CHECK_ALIGN
  131. LOCAL    void    sig        __PR((int));
  132.  
  133. LOCAL void
  134. sig(signo)
  135.     int    signo;
  136. {
  137.     signal(signo, sig);
  138.     longjmp(jb, 1);
  139. }
  140. #endif
  141.  
  142. #if defined(mc68000) || defined(mc68020)
  143. #define    MIN_ALIGN    2
  144. #else
  145. #define    MIN_ALIGN    2
  146. #endif
  147.  
  148.  
  149. #define    min_align(i)    (((i) < MIN_ALIGN) ? MIN_ALIGN : (i))
  150.  
  151. char    al[] = "alignment value for ";
  152. char    ms[] = "alignment mask  for ";
  153. char    so[] = "sizeof ";
  154. char    sh[] = "short";
  155. char    in[] = "int";
  156. char    lo[] = "long";
  157. char    ll[] = "long long";
  158. char    fl[] = "float";
  159. char    db[] = "double";
  160. char    pt[] = "pointer";
  161.  
  162. #define    xalign(x, a, m)        ( ((char *)(x)) + ( (a) - (((int)(x))&(m))) )
  163.  
  164. EXPORT int
  165. main(ac, av)
  166.     int    ac;
  167.     char    **av;
  168. {
  169.     char    *p;
  170.     int    i;
  171.     int    s;
  172.  
  173. #ifdef    CHECK_ALIGN
  174.     signal(SIGBUS, sig);
  175. #endif
  176.  
  177.     i = ((int)buf) % 1024;
  178.     i = 1024 - i;
  179.     p = &buf[i];
  180.     buf_aligned = p;
  181.  
  182. #ifdef    DEBUG
  183.     printf("buf: %lX %lX\n",
  184.         (unsigned long)buf, (unsigned long)xalign(buf, 1024, 1023));
  185. #endif
  186.  
  187.     printf("/*\n");
  188.     printf(" * This file has been generated automatically\n");
  189.     printf(" * by %s\n", sccsid);
  190.     printf(" * do not edit by hand.\n");
  191.     printf(" */\n");
  192.     printf("#ifndef    _UTYPES_H\n");
  193.     printf("#include <utypes.h>\n");
  194.     printf("#endif\n");
  195.  
  196.     s = sizeof(short);
  197.     i  = ALIGN_short;
  198.     i = min_align(i);
  199.     printf("\n");
  200.     printf("#define    ALIGN_SHORT    %d\t/* %s(%s *)\t*/\n", i, al, sh);
  201.     printf("#define    ALIGN_SMASK    %d\t/* %s(%s *)\t*/\n", i-1, ms, sh);
  202.     printf("#define    SIZE_SHORT    %d\t/* %s(%s)\t\t\t*/\n", s, so, sh);
  203.  
  204.     s = sizeof(int);
  205.     i  = ALIGN_int;
  206.     i = min_align(i);
  207.     printf("\n");
  208.     printf("#define    ALIGN_INT    %d\t/* %s(%s *)\t\t*/\n", i, al, in);
  209.     printf("#define    ALIGN_IMASK    %d\t/* %s(%s *)\t\t*/\n", i-1, ms, in);
  210.     printf("#define    SIZE_INT    %d\t/* %s(%s)\t\t\t\t*/\n", s, so, in);
  211.  
  212.     s = sizeof(long);
  213.     i  = ALIGN_long;
  214.     i = min_align(i);
  215.     printf("\n");
  216.     printf("#define    ALIGN_LONG    %d\t/* %s(%s *)\t\t*/\n", i, al, lo);
  217.     printf("#define    ALIGN_LMASK    %d\t/* %s(%s *)\t\t*/\n", i-1, ms, lo);
  218.     printf("#define    SIZE_LONG    %d\t/* %s(%s)\t\t\t*/\n", s, so, lo);
  219.  
  220. #ifdef    HAVE_LONGLONG
  221.     s = sizeof(long long);
  222.     i  = ALIGN_longlong;
  223.     i = min_align(i);
  224. #endif
  225.     printf("\n");
  226.     printf("#define    ALIGN_LLONG    %d\t/* %s(%s *)\t*/\n", i, al, ll);
  227.     printf("#define    ALIGN_LLMASK    %d\t/* %s(%s *)\t*/\n", i-1, ms, ll);
  228.     printf("#define    SIZE_LLONG    %d\t/* %s(%s)\t\t\t*/\n", s, so, ll);
  229.  
  230.     s = sizeof(float);
  231.     i  = ALIGN_float;
  232.     i = min_align(i);
  233.     printf("\n");
  234.     printf("#define    ALIGN_FLOAT    %d\t/* %s(%s *)\t*/\n", i, al, fl);
  235.     printf("#define    ALIGN_FMASK    %d\t/* %s(%s *)\t*/\n", i-1, ms, fl);
  236.     printf("#define    SIZE_FLOAT    %d\t/* %s(%s)\t\t\t*/\n", s, so, fl);
  237.  
  238.     s = sizeof(double);
  239.     i  = ALIGN_double;
  240.     i = min_align(i);
  241.     printf("\n");
  242.     printf("#define    ALIGN_DOUBLE    %d\t/* %s(%s *)\t*/\n", i, al, db);
  243.     printf("#define    ALIGN_DMASK    %d\t/* %s(%s *)\t*/\n", i-1, ms, db);
  244.     printf("#define    SIZE_DOUBLE    %d\t/* %s(%s)\t\t\t*/\n", s, so, db);
  245.  
  246.     s = sizeof(char *);
  247.     i  = ALIGN_ptr;
  248.     i = min_align(i);
  249.     printf("\n");
  250.     printf("#define    ALIGN_PTR    %d\t/* %s(%s *)\t*/\n", i, al, pt);
  251.     printf("#define    ALIGN_PMASK    %d\t/* %s(%s *)\t*/\n", i-1, ms, pt);
  252.     printf("#define    SIZE_PTR    %d\t/* %s(%s)\t\t\t*/\n", s, so, pt);
  253.  
  254.     printmacs();
  255.     return (0);
  256. }
  257.  
  258. LOCAL void
  259. printmacs()
  260. {
  261. printf("\n\n");
  262. printf("/*\n * There used to be a cast to an int but we get a warning from GCC.\n");
  263. printf(" * This warning message from GCC is wrong.\n");
  264. printf(" * Believe me that this macro would even be usable if I would cast to short.\n");
  265. printf(" * In order to avoid this warning, we are now using UIntptr_t\n */\n");
  266. /*printf("\n");*/
  267. /*printf("\n");*/
  268. printf("#define    xaligned(a, s)        ((((UIntptr_t)(a)) & s) == 0 )\n");
  269. printf("#define    x2aligned(a, b, s)    (((((UIntptr_t)(a)) | ((UIntptr_t)(b))) & s) == 0 )\n");
  270. printf("\n");
  271. printf("#define    saligned(a)        xaligned(a, ALIGN_SMASK)\n");
  272. printf("#define    s2aligned(a, b)        x2aligned(a, b, ALIGN_SMASK)\n");
  273. printf("\n");
  274. printf("#define    ialigned(a)        xaligned(a, ALIGN_IMASK)\n");
  275. printf("#define    i2aligned(a, b)        x2aligned(a, b, ALIGN_IMASK)\n");
  276. printf("\n");
  277. printf("#define    laligned(a)        xaligned(a, ALIGN_LMASK)\n");
  278. printf("#define    l2aligned(a, b)        x2aligned(a, b, ALIGN_LMASK)\n");
  279. printf("\n");
  280. printf("#define    llaligned(a)        xaligned(a, ALIGN_LLMASK)\n");
  281. printf("#define    ll2aligned(a, b)    x2aligned(a, b, ALIGN_LLMASK)\n");
  282. printf("\n");
  283. printf("#define    faligned(a)        xaligned(a, ALIGN_FMASK)\n");
  284. printf("#define    f2aligned(a, b)        x2aligned(a, b, ALIGN_FMASK)\n");
  285. printf("\n");
  286. printf("#define    daligned(a)        xaligned(a, ALIGN_DMASK)\n");
  287. printf("#define    d2aligned(a, b)        x2aligned(a, b, ALIGN_DMASK)\n");
  288. printf("\n");
  289. printf("#define    paligned(a)        xaligned(a, ALIGN_PMASK)\n");
  290. printf("#define    p2aligned(a, b)        x2aligned(a, b, ALIGN_PMASK)\n");
  291.  
  292. printf("\n\n");
  293. printf("/*\n * There used to be a cast to an int but we get a warning from GCC.\n");
  294. printf(" * This warning message from GCC is wrong.\n");
  295. printf(" * Believe me that this macro would even be usable if I would cast to short.\n");
  296. printf(" * In order to avoid this warning, we are now using UIntptr_t\n */\n");
  297. printf("#define    xalign(x, a, m)        ( ((char *)(x)) + ( (a) - 1 - ((((UIntptr_t)(x))-1)&(m))) )\n");
  298. printf("\n");
  299. printf("#define    salign(x)        xalign((x), ALIGN_SHORT, ALIGN_SMASK)\n");
  300. printf("#define    ialign(x)        xalign((x), ALIGN_INT, ALIGN_IMASK)\n");
  301. printf("#define    lalign(x)        xalign((x), ALIGN_LONG, ALIGN_LMASK)\n");
  302. printf("#define    llalign(x)        xalign((x), ALIGN_LLONG, ALIGN_LLMASK)\n");
  303. printf("#define    falign(x)        xalign((x), ALIGN_FLOAT, ALIGN_FMASK)\n");
  304. printf("#define    dalign(x)        xalign((x), ALIGN_DOUBLE, ALIGN_DMASK)\n");
  305. printf("#define    palign(x)        xalign((x), ALIGN_PTR, ALIGN_PMASK)\n");
  306. }
  307.  
  308. #ifdef    CHECK_ALIGN
  309. /*
  310.  * Routines to compute the alignement by checking if the assignement
  311.  * causes a bus error.
  312.  * Some systems (e.g. Linux on DEC Aplha) will allow to fetch any
  313.  * type from any address. On these systems we must check the speed
  314.  * because unaligned fetches will take more time.
  315.  */
  316. LOCAL int
  317. check_align(cfunc, sfunc, tsize)
  318.     int    (*cfunc)();
  319.     void    (*sfunc)();
  320.     int    tsize;
  321. {
  322.          int    calign;
  323.          int    align;
  324.          int    tcheck;
  325.          int    t;
  326.     register int    i;
  327.     register char    *p = buf_aligned;
  328.  
  329.     for (i=1; i < 128; i++) {
  330.         if (!setjmp(jb)) {
  331.             (cfunc)(p, i);
  332.             break;
  333.         }
  334.     }
  335. #ifdef    DEBUG
  336.     printf("i: %d tsize: %d\n", i, tsize);
  337. #endif
  338.     if (i == tsize)
  339.         return (i);
  340.  
  341.     align = calign = i;
  342.     tcheck = speed_check(p, sfunc, i);
  343. #ifdef    DEBUG
  344.     printf("tcheck: %d\n", tcheck);
  345. #endif
  346.  
  347.     for (i = calign*2; i <= tsize; i *= 2) {
  348.         t = speed_check(p, sfunc, i);
  349. #ifdef    DEBUG
  350.         printf("tcheck: %d t: %d i: %d\n", tcheck, t, i);
  351.         printf("tcheck - t: %d ... * 3: %d\n",  (tcheck - t), (tcheck - t) * 3);
  352. #endif
  353.         if (((tcheck - t) > 0) && ((tcheck - t) * 3) > tcheck) {
  354. #ifdef    DEBUG
  355.             printf("kleiner\n");
  356. #endif
  357.             align = i;
  358.             tcheck = t;
  359.         }
  360.     }
  361.     return (align);
  362. }
  363.  
  364. LOCAL int
  365. check_short(p, i)
  366.     char    *p;
  367.     int    i;
  368. {
  369.     short    *sp;
  370.  
  371.     sp = (short *)&p[i];
  372.     *sp = 1;
  373.     return (0);
  374. }
  375.  
  376. LOCAL int
  377. check_int(p, i)
  378.     char    *p;
  379.     int    i;
  380. {
  381.     int    *ip;
  382.  
  383.     ip = (int *)&p[i];
  384.     *ip = 1;
  385.     return (0);
  386. }
  387.  
  388. LOCAL int
  389. check_long(p, i)
  390.     char    *p;
  391.     int    i;
  392. {
  393.     long    *lp;
  394.  
  395.     lp = (long *)&p[i];
  396.     *lp = 1;
  397.     return (0);
  398. }
  399.  
  400. #ifdef    HAVE_LONGLONG
  401. LOCAL int
  402. check_longlong(p, i)
  403.     char    *p;
  404.     int    i;
  405. {
  406.     long long    *llp;
  407.  
  408.     llp = (long long *)&p[i];
  409.     *llp = 1;
  410.     return (0);
  411. }
  412. #endif
  413.  
  414. LOCAL int
  415. check_float(p, i)
  416.     char    *p;
  417.     int    i;
  418. {
  419.     float    *fp;
  420.  
  421.     fp = (float *)&p[i];
  422.     *fp = 1.0;
  423.     return (0);
  424. }
  425.  
  426. LOCAL int
  427. check_double(p, i)
  428.     char    *p;
  429.     int    i;
  430. {
  431.     double    *dp;
  432.  
  433.     dp = (double *)&p[i];
  434.     *dp = 1.0;
  435.     return (0);
  436. }
  437.  
  438. LOCAL int
  439. check_ptr(p, i)
  440.     char    *p;
  441.     int    i;
  442. {
  443.     char    **pp;
  444.  
  445.     pp = (char  **)&p[i];
  446.     *pp = (char *)1;
  447.     return (0);
  448. }
  449.  
  450. /*
  451.  * Routines to compute the alignement by checking the speed of the
  452.  * assignement.
  453.  * Some systems (e.g. Linux on DEC Aplha) will allow to fetch any
  454.  * type from any address. On these systems we must check the speed
  455.  * because unaligned fetches will take more time.
  456.  */
  457. LOCAL void
  458. speed_short(p, n)
  459.     char    *p;
  460.     int    n;
  461. {
  462.     short    *sp;
  463.     int    i;
  464.  
  465.     sp = (short *)&p[n];
  466.  
  467.     for (i = 1000000; --i >= 0;)
  468.         *sp = i;
  469. }
  470.  
  471. LOCAL void
  472. speed_int(p, n)
  473.     char    *p;
  474.     int    n;
  475. {
  476.     int    *ip;
  477.     int    i;
  478.  
  479.     ip = (int *)&p[n];
  480.  
  481.     for (i = 1000000; --i >= 0;)
  482.         *ip = i;
  483. }
  484.  
  485. LOCAL void
  486. speed_long(p, n)
  487.     char    *p;
  488.     int    n;
  489. {
  490.     long    *lp;
  491.     int    i;
  492.  
  493.     lp = (long *)&p[n];
  494.  
  495.     for (i = 1000000; --i >= 0;)
  496.         *lp = i;
  497. }
  498.  
  499. #ifdef    HAVE_LONGLONG
  500. LOCAL void
  501. speed_longlong(p, n)
  502.     char    *p;
  503.     int    n;
  504. {
  505.     long long *llp;
  506.     int    i;
  507.  
  508.     llp = (long long *)&p[n];
  509.  
  510.     for (i = 1000000; --i >= 0;)
  511.         *llp = i;
  512. }
  513. #endif
  514.  
  515. LOCAL void
  516. speed_float(p, n)
  517.     char    *p;
  518.     int    n;
  519. {
  520.     float    *fp;
  521.     int    i;
  522.  
  523.     fp = (float *)&p[n];
  524.  
  525.     for (i = 1000000; --i >= 0;)
  526.         *fp = i;
  527. }
  528.  
  529. LOCAL void
  530. speed_double(p, n)
  531.     char    *p;
  532.     int    n;
  533. {
  534.     double    *dp;
  535.     int    i;
  536.  
  537.     dp = (double *)&p[n];
  538.  
  539.     for (i = 1000000; --i >= 0;)
  540.         *dp = i;
  541. }
  542.  
  543. LOCAL void
  544. speed_ptr(p, n)
  545.     char    *p;
  546.     int    n;
  547. {
  548.     char    **pp;
  549.     int    i;
  550.  
  551.     pp = (char **)&p[n];
  552.  
  553.     for (i = 1000000; --i >= 0;)
  554.         *pp = (char *)i;
  555. }
  556.  
  557. #include <sys/times.h>
  558. LOCAL int
  559. speed_check(p, sfunc, n)
  560.     char    *p;
  561.     void    (*sfunc)();
  562.     int    n;
  563. {
  564.     struct tms tm1;
  565.     struct tms tm2;
  566.  
  567.     times(&tm1);
  568.     (*sfunc)(p, n);
  569.     times(&tm2);
  570.  
  571. #ifdef    DEBUG
  572.     printf("t1: %ld\n", (long) tm2.tms_utime-tm1.tms_utime);
  573. #endif
  574.  
  575.     return ((int) tm2.tms_utime-tm1.tms_utime);
  576. }
  577.  
  578. #endif    /* CHECK_ALIGN */
  579.  
  580. #ifdef    OFF_ALIGN
  581. /*
  582.  * Routines to compute the alignement by using the knowledge
  583.  * of the C-compiler.
  584.  * We define a structure and check the padding that has been inserted
  585.  * by the compiler to keep the apropriate type on a properly aligned
  586.  * address.
  587.  */
  588. LOCAL int
  589. off_short()
  590. {
  591.     struct ss {
  592.         char    c;
  593.         short    s;
  594.     } ss;
  595.     ss.c = 0;        /* fool C-compiler */
  596.  
  597.     return (sm_off(struct ss *, s));
  598. }
  599.  
  600. LOCAL int
  601. off_int()
  602. {
  603.     struct si {
  604.         char    c;
  605.         int    i;
  606.     } si;
  607.     si.c = 0;        /* fool C-compiler */
  608.  
  609.     return (sm_off(struct si *, i));
  610. }
  611.  
  612. LOCAL int
  613. off_long()
  614. {
  615.     struct sl {
  616.         char    c;
  617.         long    l;
  618.     } sl;
  619.     sl.c = 0;        /* fool C-compiler */
  620.  
  621.     return (sm_off(struct sl *, l));
  622. }
  623.  
  624. #ifdef    HAVE_LONGLONG
  625. LOCAL int
  626. off_longlong()
  627. {
  628.     struct sll {
  629.         char    c;
  630.         long long    ll;
  631.     } sll;
  632.     sll.c = 0;        /* fool C-compiler */
  633.  
  634.     return (sm_off(struct sll *, ll));
  635. }
  636. #endif
  637.  
  638. LOCAL int
  639. off_float()
  640. {
  641.     struct sf {
  642.         char    c;
  643.         float    f;
  644.     } sf;
  645.     sf.c = 0;        /* fool C-compiler */
  646.  
  647.     return (sm_off(struct sf *, f));
  648. }
  649.  
  650. LOCAL int
  651. off_double()
  652. {
  653.     struct sd {
  654.         char    c;
  655.         double    d;
  656.     } sd;
  657.     sd.c = 0;        /* fool C-compiler */
  658.  
  659.     return (sm_off(struct sd *, d));
  660. }
  661.  
  662. LOCAL int
  663. off_ptr()
  664. {
  665.     struct sp {
  666.         char    c;
  667.         char    *p;
  668.     } sp;
  669.     sp.c = 0;        /* fool C-compiler */
  670.  
  671.     return (sm_off(struct sp *, p));
  672. }
  673.  
  674. #endif    /* OFF_ALIGN */
  675.